package com.wanxi.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wanxi.config.ProductRepository;
import com.wanxi.dao.ProductDao;
import com.wanxi.model.ProductModel;
import com.wanxi.model.ResultModel;
import com.wanxi.service.ProductService;
import com.wanxi.util.SnowflakeIdWorker;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author 杨金乾
 */
@Service
public class ProductServiceImpl implements ProductService {
    @Autowired
    ProductDao productDao;

    @Autowired
    ProductRepository productRepository;

    @Resource
    ElasticsearchRestTemplate elasticsearchRestTemplate;
    public static ThreadPoolExecutor es = new ThreadPoolExecutor(50, 100, 0L, TimeUnit.SECONDS,new LinkedBlockingQueue());
    @Override
    public ResultModel add(ProductModel productModel) {

        SnowflakeIdWorker snowflakeIdWorker=new SnowflakeIdWorker(WorkId.WORK_ID);
        productModel.setId(snowflakeIdWorker.nextId());
        return ResultModel.getResult(productDao.add(productModel));
    }

    @Override
    public ResultModel enable(ProductModel productModel) {

        return ResultModel.getResult(productDao.enable(productModel));
    }

    @Override
    public ResultModel isShow(ProductModel productModel) {

        return ResultModel.getResult(productDao.isShow(productModel));
    }

    @Override
    public ResultModel isRecommend(ProductModel productModel) {
        return ResultModel.getResult(productDao.isRecommend(productModel));
    }

    @Override
    public ResultModel whereShow(ProductModel productModel) {

        return ResultModel.getResult(productDao.whereShow(productModel));
    }

    @Override
    public ResultModel update(ProductModel productModel) {

        return ResultModel.getResult(productDao.update(productModel));
    }

    @Override
    public ResultModel delete(ProductModel productModel) {
        return ResultModel.getResult(productDao.delete(productModel));
    }

    @Override
    public ResultModel findById(ProductModel productModel) {

        return ResultModel.getResult(productDao.findById(productModel));
    }

    @Override
    public ResultModel findAll(ProductModel productModel) {

        productModel.setLimit(10);
        productModel.setPage((productModel.getPage()-1)*10);
        return ResultModel.getResult(productDao.findAll(productModel), productDao.count(productModel));
    }


    @Override
    public ResultModel count(ProductModel productModel) {

        return ResultModel.getResult(productDao.count(productModel));
    }


    @Override
    public List<ProductModel> searchByProductModelEs(ProductModel productModel) {
        PageRequest pageRequest=PageRequest.of(productModel.getPage()-1,productModel.getLimit(), Sort.Direction.DESC,"id");
        if (!"".equals(productModel.getName())&&productModel.getName()!=null){
            if (productModel.getClothingStyleId()!=null&&productModel.getClothingStyleId()!=-1){
                // 创建一个高亮field
                HighlightBuilder.Field field = new HighlightBuilder.Field("name")
                        .preTags("<font color='red'>")
                        .postTags("</font>");
                // 构建一个本地查询NativeSearchQuery，通过matchQuery
                NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                        .withQuery(QueryBuilders.boolQuery()
                                .must(QueryBuilders.matchQuery("name",productModel.getName()))
                                .must(QueryBuilders.matchQuery("clothingStyleId",productModel.getClothingStyleId()))
                                .filter(QueryBuilders.rangeQuery("price").gte(productModel.getPriceStart()).lte(productModel.getPriceEnd()))).withHighlightFields(field).build();
                nativeSearchQuery.setPageable(pageRequest);
                SearchHits<ProductModel> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery,ProductModel.class);
                // 把高亮的数据替换到email里
                List<ProductModel> productModelEsList = searchHits.stream().map((x)-> {
                    ProductModel newProductModel = x.getContent();
                    newProductModel.setName(x.getHighlightField("name").get(0));
                    return newProductModel;
                }).collect(Collectors.toList());
                return productModelEsList;
            }else {
                // 创建一个高亮field
                HighlightBuilder.Field field = new HighlightBuilder.Field("name")
                        .preTags("<font color='red'>")
                        .postTags("</font>");
                // 构建一个本地查询NativeSearchQuery，通过matchQuery
                NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                        .withQuery(QueryBuilders.boolQuery()
                                .must(QueryBuilders.matchQuery("name",productModel.getName()))
                                .filter(QueryBuilders.rangeQuery("price")
                                        .gte(productModel.getPriceStart())
                                        .lte(productModel.getPriceEnd())))
                        .withHighlightFields(field).build();
                nativeSearchQuery.setPageable(pageRequest);
                SearchHits<ProductModel> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery,ProductModel.class);
                // 把高亮的数据替换到email里
                List<ProductModel> productModelEsList = searchHits.stream().map((x)-> {
                    ProductModel newProductModel = x.getContent();
                    newProductModel.setName(x.getHighlightField("name").get(0));
                    return newProductModel;
                }).collect(Collectors.toList());
                return productModelEsList;
            }

        }else {
            if (productModel.getClothingStyleId()!=null&&productModel.getClothingStyleId()!=-1){
                // 构建一个本地查询NativeSearchQuery，通过matchQuery
                NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                        .withQuery(QueryBuilders.boolQuery()
                                .must(QueryBuilders.matchQuery("clothingStyleId",productModel.getClothingStyleId()))
                                .filter(QueryBuilders.rangeQuery("price").gte(productModel.getPriceStart()).lte(productModel.getPriceEnd()))).build();
                nativeSearchQuery.setPageable(pageRequest);
                SearchHits<ProductModel> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery,ProductModel.class);
                List<ProductModel> productModelEsList = searchHits.stream().map((x)-> x.getContent()).collect(Collectors.toList());
                return productModelEsList;
            }else if (productModel.getPriceEnd()!=null||productModel.getPriceStart()!=null){
                // 构建一个本地查询NativeSearchQuery，通过matchQuery
                NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                        .withQuery(QueryBuilders.boolQuery()
                                .filter(QueryBuilders.rangeQuery("price").gte(productModel.getPriceStart()).lte(productModel.getPriceEnd()))).build();
                nativeSearchQuery.setPageable(pageRequest);
                SearchHits<ProductModel> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery,ProductModel.class);

                List<ProductModel> productModelEsList = searchHits.stream().map((x)-> x.getContent()).collect(Collectors.toList());
                return productModelEsList;
            }else {
                // 构建一个本地查询NativeSearchQuery，通过matchQuery
                NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                        .withQuery(QueryBuilders.matchAllQuery()).build();
                nativeSearchQuery.setPageable(pageRequest);
                SearchHits<ProductModel> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery,ProductModel.class);
                List<ProductModel> productModelEsList = searchHits.stream().map((x)-> x.getContent()).collect(Collectors.toList());
                return productModelEsList;
            }
        }

    }

    @Override
    public void saveEsByContent(ProductModel productModel) {
        //查询全部数据
        List<ProductModel> content = productDao.findAllEs(productModel);
        //获取总数
        int total = content.size();
        //定义每页个数 --前台传来
        final int pagesize = 10;
        //求出当每页为pagesize 时候，可以分几页，就循环几次 ，分页插入
        int pagenum = (int) Math.ceil(total / pagesize);
        System.out.println("一共有"+(pagenum+1)+"页");
        //分页导入
        for (int i = 0; i <= pagenum; i++) {
            //分页对象 mybatis 提供的
            PageHelper.startPage(i,pagesize);
            PageInfo<ProductModel> tcmFilePageInfo = new PageInfo(content);
            System.out.println("正在导入第" + (i+1) + "页数据");
            if(tcmFilePageInfo.getSize()>0){
                es.submit(()->{
                    productRepository.saveAll(tcmFilePageInfo.getList());
                });
            }
        }

        System.out.println("导入完毕！");

    }
}


